/*
 * $Id: SystemResource.java,v 1.7 2009/10/21 18:50:13 oliver Exp $
 * 
 * Copyright (C) 2006 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.common.load.system;

import java.io.Serializable;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.database.dao.ISystemLoadParamDAO;
import com.ge.healthcare.autosc.common.database.pojo.CfgSystemLoadParam;
import com.ge.healthcare.autosc.common.load.IResourceQueue;
import com.ge.healthcare.autosc.common.pojo.TaskNResource;
import com.ge.healthcare.autosc.common.util.ApplicationInfo;
import com.ge.healthcare.autosc.common.util.PropertyConstants;

public class SystemResource implements ISystemResource, Serializable {
	/**
	 * Eclipse generated
	 */
	private static final long serialVersionUID = -7367170269534825430L;
	private Long minPriority = null;
	private IResourceQueue categoryResource;
	private IResourceQueue svcResource;
	private IResourceQueue pmResource;
	private ISystemLoadParamDAO systemLoadParamDAO;
	private static final String SWEEP_TYPE = "SWEEP";

	public String toString(){
		StringBuffer sb = new StringBuffer();
		sb.append("SystemResource categoryResource:[ ").append(categoryResource);
		sb.append("] svcResource: [").append(svcResource);
		sb.append("] pmResource: [").append(pmResource).append("]");
		return sb.toString();
	}
	public SystemResource(ISystemLoadParamDAO sysLPDAO) {
		this.systemLoadParamDAO = sysLPDAO;
		resetQueue();
	}
	public SystemResource(ISystemLoadParamDAO sysLPDAO, int multiplier) {
		this.systemLoadParamDAO = sysLPDAO;
		resetQueue(multiplier);
	}
	/**
	 * reset queue to default values. Note this is needed for testing only at
	 * the start. Make sure you understand the implications of doing this for
	 * something other than testing
	 */
	public void resetQueue(){
		resetQueue(1);
	}
	public void resetQueue(int multiplier){
		minPriority = Long.valueOf(ApplicationInfo.getInstance()
				.getLongPropertyValue(PropertyConstants.TASK_PRIORITY_LEVEL));
		categoryResource = systemLoadParamDAO
				.getLoadParamByType(CfgSystemLoadParam.TYPE_CATIGORY, multiplier);
		svcResource = systemLoadParamDAO
				.getLoadParamByType(CfgSystemLoadParam.TYPE_SVC_CENTER, multiplier);
		pmResource = systemLoadParamDAO
				.getLoadParamByType(CfgSystemLoadParam.TYPE_PORTMASTER, multiplier);
	}
	public boolean consume(TaskNResource task) {
		StringBuffer msg = new StringBuffer();
		msg.append("TaskNResource: ").append(task);
		boolean isConsumable = true;
		if (!isAboveDefCon(task)) {
			msg.append("Is Below Current DefCon level ");
			isConsumable = false;
		} else {
			// Category Consume
			if (!categoryResource.consume(task)) {
				msg.append("No Resources for Type Avialable ");
				isConsumable = false;
			}
		}
		if (isConsumable && SWEEP_TYPE.equals(task.getCategory())) {
			msg.append("Is of Sweep Type ");
			// connectivity consume
			if (task.isDialUpSystem()) {
				if (!pmResource.consume(task)) {
					msg.append("No PortMaster resouces Avialable ");
					isConsumable = false;
				}
			} else {
				if (!svcResource.consume(task)) {
					msg.append("No Service Center resouces Avialable ");
					isConsumable = false;
				}
			}
		}
		if (!isConsumable) {
			categoryResource.release(task);
			pmResource.release(task);
			svcResource.release(task);
		} else {
			msg.append("Task Consumed Sucessfully ");
		}
		ASCLogger.info(this.getClass(), "Comsume", msg.toString());
		return isConsumable;
	}

	/**
	 * Determine if a task is above the systems current DefCon (Defense
	 * Condition - See 80s movie "War Games") WJO I am not using logic from
	 * StatusCheck to prevent unnecessary data reads
	 * 
	 * @param task
	 * @return
	 */
	public boolean isAboveDefCon(TaskNResource task) {
		if (ASCUtil.isNullOrEmptyObject(task.getPriority())) {
			throw new RuntimeException(
					"TASK_PRIORITY_LEVEL was not found property");
		}
		int compareVal = minPriority.compareTo(task.getPriority());
		if ((compareVal >= 0)) {
			return true;
		}
		return false;
	}

	public int categoryMax(String category) {
		return categoryResource.max(category);
	}

	public int categorySize(String category) {
		return categoryResource.size(category);
	}

	public int svcMax(String svcCenter) {
		return svcResource.max(svcCenter);
	}

	public int svcSize(String svcCenter) {
		return svcResource.size(svcCenter);
	}

	public int portMasterMax(String portMaster) {
		return pmResource.max(portMaster);
	}

	public int portMasterSize(String portMaster) {
		return pmResource.size(portMaster);
	}

	/**
	 * @param systemLoadParamDAO
	 *            the systemLoadParamDAO to set
	 */
	public void setSystemLoadParamDAO(ISystemLoadParamDAO systemLoadParamDAO) {
		this.systemLoadParamDAO = systemLoadParamDAO;
	}

	public boolean isConsumed(TaskNResource task) {
		StringBuffer msg = new StringBuffer();
		msg.append("TaskNResource: ").append(task);
		boolean isConsumed = true;

		if (!categoryResource.contains(task)) {
			msg.append("Task not contained in Queue");
			isConsumed = false;
		}
		if (isConsumed && SWEEP_TYPE.equals(task.getCategory())) {
			msg.append("Is of Sweep Type ");
			// connectivity consume
			if (task.isDialUpSystem()) {
				if (!pmResource.contains(task)) {
					msg.append("No PortMaster resouces Avialable ");
					isConsumed = false;
				}
			} else {
				if (!svcResource.contains(task)) {
					msg.append("No Service Center resouces Avialable ");
					isConsumed = false;
				}
			}
		}
		ASCLogger.info(this.getClass(), "isConsumed", msg.toString());
		return isConsumed;
	}

	public void release(TaskNResource task) {
		categoryResource.release(task);
		pmResource.release(task);
		svcResource.release(task);
	}
	/**
	 * 
	 * @return ISystemResource
	 */
	public ISystemResource copy(int multiplier){
		ISystemResource sysResource = new SystemResource(this.systemLoadParamDAO, multiplier);
		sysResource.copyCategoryResource(categoryResource);
		sysResource.copyServiceCenterResource(svcResource);
		sysResource.copyPortMasterResource(pmResource);
		
		return sysResource;
	}
	public void copyCategoryResource(IResourceQueue categoryResource) {
		this.categoryResource.copy(categoryResource);
	}
	public void copyPortMasterResource(IResourceQueue pmResource) {
		this.pmResource.copy(pmResource);
	}
	public void copyServiceCenterResource(IResourceQueue svcResource) {
		this.svcResource.copy(svcResource);
	}

}
